﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Dapper.Sharding
{
    public class ConfigJsonNet
    {
        public static JObject LoadObject(string jsonFile, string key = null)
        {
            var file = $"{AppDomain.CurrentDomain.BaseDirectory}{jsonFile}";
            var text = File.ReadAllText(file);
            var obj = JsonConvert.DeserializeObject<JObject>(text);
            if (!string.IsNullOrEmpty(key))
            {
                obj = (JObject)obj[key];
            }
            return obj;
        }

        public static ClientConfig LoadConfig(JObject obj)
        {
            var cfg = new ClientConfig();
            cfg.Config = obj.ToObject<DataBaseConfig>();

            if (obj.TryGetValue("AutoCreateDatabase", StringComparison.CurrentCultureIgnoreCase, out JToken node))
            {
                cfg.AutoCreateDatabase = node.Value<bool>();
            }

            if (obj.TryGetValue("AutoCreateTable", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                cfg.AutoCreateTable = node.Value<bool>();
            }

            if (obj.TryGetValue("AutoCompareTableColumn", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                cfg.AutoCompareTableColumn = node.Value<bool>();
            }

            if (obj.TryGetValue("AutoCompareTableColumnLength", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                cfg.AutoCompareTableColumnLength = node.Value<bool>();
            }

            if (obj.TryGetValue("AutoCompareTableColumnDelete", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                cfg.AutoCompareTableColumnDelete = node.Value<bool>();
            }

            if (obj.TryGetValue("Database", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                cfg.Database = node.Value<string>();
            }

            if (obj.TryGetValue("Id", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                cfg.Id = node.Value<string>();
            }

            if (obj.TryGetValue("DatabaseList", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                cfg.DatabaseList = node.Values<string>().ToList();
            }

            cfg.DbType = DataBaseType.MySql;
            if (obj.TryGetValue("DbType", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                var dbType = node.Value<string>().ToLower();
                if (dbType == "mysql")
                {
                    cfg.DbType = DataBaseType.MySql;
                }
                else if (dbType == "postgresql" || dbType == "pgsql")
                {
                    cfg.DbType = DataBaseType.Postgresql;
                }
                else if (dbType == "sqlserver")
                {
                    cfg.DbType = DataBaseType.SqlServer;
                }
                else if (dbType == "oracle")
                {
                    cfg.DbType = DataBaseType.Oracle;
                }
                else if (dbType == "sqlite")
                {
                    cfg.DbType = DataBaseType.Sqlite;
                }
                else if (dbType == "clickhouse")
                {
                    cfg.DbType = DataBaseType.ClickHouse;
                }

                throw new Exception($"unknown DbType==>{dbType}");
            }

            cfg.DbVersion = DataBaseVersion.Default;
            if (obj.TryGetValue("DbVersion", StringComparison.CurrentCultureIgnoreCase, out node))
            {
                var version = node.Value<string>().ToLower();
                if (version == "sqlserver2005")
                {
                    cfg.DbVersion = DataBaseVersion.SqlServer2005;
                }
                else if (version == "sqlserver2008")
                {
                    cfg.DbVersion = DataBaseVersion.SqlServer2008;
                }
                else if (version == "sqlserver2012")
                {
                    cfg.DbVersion = DataBaseVersion.SqlServer2012;
                }
            }

            return cfg;
        }

        public static ClientConfig LoadConfig(string jsonFile, string key = null)
        {
            var obj = LoadObject(jsonFile, key);
            return LoadConfig(obj);
        }

        public static JArray LoadArray(string jsonFile, string key = null)
        {
            var file = $"{AppDomain.CurrentDomain.BaseDirectory}{jsonFile}";
            var text = File.ReadAllText(file);
            if (!string.IsNullOrEmpty(key))
            {
                var obj = JsonConvert.DeserializeObject<JObject>(text);
                return (JArray)obj[key];
            }

            return JsonConvert.DeserializeObject<JArray>(text);
        }

        public static List<ClientConfig> LoadConfigList(JArray array)
        {
            var list = new List<ClientConfig>();
            foreach (var item in array.Cast<JObject>())
            {
                list.Add(LoadConfig(item));
            }
            return list;
        }

        public static List<ClientConfig> LoadConfigList(string jsonFile, string key = null)
        {
            var array = LoadArray(jsonFile, key);
            return LoadConfigList(array);
        }

    }
}
